import angular from 'angular'
import '@yunke/core/angular_public_interceptor'
import _ from 'lodash'

angular.module('ApiService', ['angularPublicInterceptor'])
    .provider('api', function () {

        const _service = {};

        let $http;

        let $q;

        /**
         * 集合操作 对象 数组 字符串 camelCase
         * @param xs
         * @returns {*}
         */
        const mapCamelCase = xs => {

            const camelCase = x => {

                const values = _.mapValues(x, (value) => {

                    if (_.isObject(value) || _.isArray(value)) {
                        return mapCamelCase(value);
                    } else {
                        return value;
                    }

                });

                return _.mapKeys(values, (value, key) => _.camelCase(key))

            };

            if (_.isArray(xs)) {
                if (_.some(xs, x => !_.isObject(x))) {
                    return xs;
                }
                return _.map(xs, camelCase);
            } else if (_.isObject(xs)) {
                return camelCase(xs);
            } else if (_.isString(xs)) {
                return _.camelCase(xs);
            } else {
                return xs;
            }

        };

        const service = {
            pageIndex: 1,
            pageSize: 10,
            apis: {},
            camelCase: false,
            useFormData: true,
            getService: () => {
                _.zipObject(_.each(_.keys(service.apis), (p) => {
                    _service[p] = createService(p, service.apis);
                }));
                return _service;
            },
            getUrl: (name) => service.apis[name].url,
            setPageIndex: (v) => service.pageIndex = v,
            setPageSize: (v) => service.pageSize = v,
            setApis: (urls) => service.apis = _.merge(urls, service.apis),
            setCamelCase: (v) => service.camelCase = v,
            setUseFormData: (v) => service.useFormData = v
        };

        const createService = (p, xo, defaultMethod = 'get') => {
            const x = xo[p];
            return (data = {}, search = '') => {
                if (x.method === undefined || x.method == defaultMethod) {
                    x.method = defaultMethod;
                    data = {
                        params: data
                    };
                } else {
                    data = _.merge({USE_FORM_DATA: service.useFormData}, data);
                }
                if (service.camelCase) {
                    return $http[x.method](x.url + search, data)
                        .then(res => $q.resolve(mapCamelCase(res)), $q.reject);
                } else {
                    return $http[x.method](x.url + search, data);
                }

            }
        };

        const getApi = (_$http, _$q) => {
            $http = _$http;
            $q = _$q;
            return service;
        };

        this.$get = ($http, $q) => getApi($http, $q);

    });